import java.util.ArrayList;
import java.util.Arrays;

import static java.lang.System.err;
import static java.lang.System.out;

public abstract class FixedDepth extends ComputerPlayer {
    public FixedDepth(boolean isBlack, Eval evaluator, int searchDepth) {
        super(isBlack, evaluator, searchDepth);
    }


    public abstract Board findMove(Board board);


    @Override
    public Action getMove(Board board, int moveNbr) {

        nbrNodesVisited = 0;
        Arrays.fill(nbrMovesCount, 0);
        Arrays.fill(depthCount, 0);

        long startTime = System.currentTimeMillis();

        assert board.blackToMove == isBlack;
        Board bestMove = findMove(board);

        int[] myMove;
        if (bestMove != null) {
            myMove = movePathFromBoards(board, bestMove);
            out.print("My move is " + moveNbr + ": " + myMove[0]);
            for (int i = 1; i < myMove.length; i++) {
                out.print(" - " + myMove[i]);
            }
            out.println();
        } else {
            out.println(color + " couldn't find any available moves.");
            myMove = new int[0];
        }

        long endTime = System.currentTimeMillis();
        long thisMove = endTime - startTime;
        spentTime += thisMove;
        float thisMoveTotalTime = thisMove / 1000.0F;
        float totalTime = spentTime / 1000.0F;
        out.printf("This move took: %.2f s.\n", thisMoveTotalTime);
        out.printf("Total spent time: %.2f s.\n", totalTime);

        // Print nodes per second
        out.println();
        out.printf("During this move the program visited %d nodes.\n",
                   nbrNodesVisited);
        if (thisMoveTotalTime > 0.0) {
            double nodesPerSecond =
                ((double) nbrNodesVisited) / thisMoveTotalTime;
            out.printf("During this move the program visited: %.0f nodes"
                       + " / second.\n", nodesPerSecond);
        }

        // Print move count
        out.println();
        out.println("Stats for number of moves for a board during this move:");
        printStats(nbrMovesCount);

        // Print depth count
        out.println();
        out.println("Stats for depth reached when search stops during this move:");
        printStats(depthCount);

        return new Action(myMove, spentTime);
    }
}
